﻿#light

module Dwarf_SparseAlgebra_Generator

open System
open System.IO
open System.Text
open System.ComponentModel
open System.Globalization   

let Dwarf_SparseAlgebra_Generator (fs : FileStream, args : String[]) = 
    
    // subsidiary objects
    let writer = new StreamWriter(fs);
    let rand = new Random();   
    
    // constants
    let average_byte_count = 4
    let count_of_digits_in_kilobyte = 1024
    let max_int = 10000

    // formulaes
    let division x = (float) (x * count_of_digits_in_kilobyte / average_byte_count)
    let dimension x = (int) (Math.Round(Math.Sqrt(division x)))

    // current data values
    let count_of_kilobytes = (int) args.[args.Length - 1]
    let current_dimension = dimension count_of_kilobytes
    
    //////////////////////////////////////////////////////////
    
    let matrixSize = current_dimension
    let capacity = 0.1
    
    let numNonZeros = ref 0;    
    let mSize = matrixSize;

    let matrix = Array2D.zeroCreate<double> mSize mSize
    let vector = Array.create<double> mSize ((double) 0)    
    
    for i = 0 to mSize - 1 do
        for j = 0 to mSize - 1 do
            if rand.NextDouble() < capacity then 
                matrix.[i, j]  <- (rand.NextDouble() * (double)1000)
                numNonZeros := !numNonZeros + 1
            else
                matrix.[i, j]  <- (double)0

        vector.[i] <- rand.NextDouble() * (double) 100000;

    let values = Array.create<double> !numNonZeros ((double) 0);
    let col_ind = Array.create !numNonZeros 0;
    let row_ptr = Array.create (mSize + 1) 0;

    row_ptr.[0] <- 1;
    let k = ref 0;
    for i = 0 to mSize - 1 do
        for j = 0 to mSize - 1 do
            if matrix.[i, j] <> (double)0 then                
                values.[!k] <- matrix.[i, j]                
                col_ind.[!k] <- j + 1
                k := !k + 1       
        row_ptr.[i + 1] <- !k + 1; 

    // write the dimension
    writer.Write(mSize);
    writer.WriteLine();
    writer.Write(!numNonZeros);
    writer.WriteLine();
        
    for i = 0 to !numNonZeros - 1 do
        writer.Write("{0} ", values.[i].ToString("F0", CultureInfo.InvariantCulture));
        
    writer.WriteLine();

    for i = 0 to !numNonZeros - 1 do
        writer.Write("{0} ", col_ind.[i]);
        
    writer.WriteLine();

    for i = 0 to mSize do
        writer.Write("{0} ", row_ptr.[i]);
        
    writer.WriteLine();

    for i = 0 to mSize - 1 do
        writer.Write("{0} ", vector.[i].ToString("F0", CultureInfo.InvariantCulture));
        
    writer.WriteLine();

    writer.Close()

    true
